/*
 * ECARX Technology Limited is the owner of the copyright and the trade secret of this software.
 * Without permission, no one has the right to obtain, disclose or use this software in any way.
 */

package com.ecarx.systemui.plugin.controller.hvac;

import android.car.VehiclePropertyIds;
import android.car.hardware.CarPropertyValue;
import android.car.hardware.property.CarPropertyManager;

import com.ecarx.systemui.plugin.AppConstants;
import com.ecarx.systemui.plugin.controller.CarSignalController;
import com.ecarx.systemui.plugin.model.listener.FanFuncNotifyViewListener;
import com.ecarx.systemui.plugin.model.listener.HvacModeListener;
import com.ecarx.systemui.plugin.utils.LogUtils;
import com.ecarx.systemui.plugin.utils.ThreadUtils;
import com.ecarx.xui.adaptapi.FunctionStatus;
import com.ecarx.xui.adaptapi.car.IWrapper;
import com.ecarx.xui.adaptapi.car.hvac.IHvac;

public class FanSignalController extends HvacBaseController implements CarPropertyManager.CarPropertyEventCallback {

    private static final String TAG = "FanSignalControllerTag";

    private FanFuncNotifyViewListener fanFuncNotifyViewListener;
    private FanFuncNotifyViewListener fanFuncNotifyDialogListener;
    private HvacModeListener hvacModeListener;
    private IWrapper.IPropertyId autoFanProperty;

    public void setFanSignalNotifyViewListener(FanFuncNotifyViewListener
                                                       fanFuncNotifyViewListener) {
        this.fanFuncNotifyViewListener = fanFuncNotifyViewListener;
    }

    public void setFanSignalNotifyDialogListener(FanFuncNotifyViewListener
                                                         fanFuncNotifyViewListener) {
        this.fanFuncNotifyDialogListener = fanFuncNotifyViewListener;
    }

    public void setHvacModeListener(HvacModeListener listener) {
        this.hvacModeListener = listener;
    }

    private static FanSignalController fanSignalController;

    private FanSignalController() {
        doRegisterSignal();
    }

    public static synchronized FanSignalController getInstance() {
        if (fanSignalController == null) {
            fanSignalController = new FanSignalController();
        }
        return fanSignalController;
    }

    private void doRegisterSignal() {
        boolean isOk = CarSignalController.checkSelf();
        if (!isOk) {
            ThreadUtils.postDelayOnMain(100, this::doRegisterSignal);
            return;
        }
        CarPropertyManager carPropertyManager =
                CarSignalController.getInstance().getCarPropertyManager();
        IWrapper wrapper = CarSignalController.getInstance().getWrapper();

        carPropertyManager.registerCallback(this,
                VehiclePropertyIds.HVAC_AUTO_ON, CarPropertyManager.SENSOR_RATE_NORMAL);
        carPropertyManager.registerCallback(this,
                VehiclePropertyIds.HVAC_FAN_SPEED, CarPropertyManager.SENSOR_RATE_NORMAL);
        autoFanProperty = wrapper.getWrappedPropertyId(
                IWrapper.WrappedIdType.ID_TYPE_FUNCTION, IHvac.HVAC_FUNC_AUTO_FAN_SETTING);
        LogUtils.d(TAG, "autoFanProperty:" + autoFanProperty);
        carPropertyManager.registerCallback(this,
                autoFanProperty.getPropertyId(), CarPropertyManager.SENSOR_RATE_NORMAL);

    }

    public void doUnRegisterSignal() {
        boolean isOk = CarSignalController.checkSelf();
        if (isOk) {
            CarPropertyManager carPropertyManager =
                    CarSignalController.getInstance().getCarPropertyManager();
            carPropertyManager.unregisterCallback(this);
        }
    }

    @Override
    public void onChangeEvent(CarPropertyValue carPropertyValue) {
        LogUtils.d(TAG, "onChangeEvent carPropertyValue:" + carPropertyValue.toString());
        int propertyId = carPropertyValue.getPropertyId();
        int status = carPropertyValue.getStatus();
        FunctionStatus functionStatus = CarSignalController.toFunctionStatus(status);
        Object value = carPropertyValue.getValue();
        if (VehiclePropertyIds.HVAC_AUTO_ON == propertyId) {
            boolean isAuto = (boolean) value;
            if (fanFuncNotifyViewListener != null) {
                fanFuncNotifyViewListener.onHvacModeChange(isAuto, functionStatus);
            }
            if (fanFuncNotifyDialogListener != null) {
                fanFuncNotifyDialogListener.onHvacModeChange(isAuto, functionStatus);
            }
            if (hvacModeListener != null) {
                hvacModeListener.onHvacModeChange(isAuto);
            }
        } else if (VehiclePropertyIds.HVAC_FAN_SPEED == propertyId) {
            boolean fanModeSwitch = getFanModeSwitch();
            if (!fanModeSwitch) {
                Integer handFanValue = (Integer) value;
                if (fanFuncNotifyViewListener != null) {
                    fanFuncNotifyViewListener.onHvacHandFanChange(handFanValue, functionStatus);
                }
                if (fanFuncNotifyDialogListener != null) {
                    fanFuncNotifyDialogListener.onHvacHandFanChange(handFanValue, functionStatus);
                }
            }
        } else if (autoFanProperty.getPropertyId() == propertyId) {
            boolean fanModeSwitch = getFanModeSwitch();
            if (fanModeSwitch) {
                int autoFanValue = (int) value;
                Integer adaptValue = autoFanProperty.getPropertyAdaptValue(autoFanValue);
                if (fanFuncNotifyViewListener != null) {
                    fanFuncNotifyViewListener.onHvacAutoFanChange(adaptValue, functionStatus);
                }
                if (fanFuncNotifyDialogListener != null) {
                    fanFuncNotifyDialogListener.onHvacAutoFanChange(adaptValue, functionStatus);
                }
            }
        }
    }

    @Override
    public void onErrorEvent(int propId, int areaId) {

    }

    public int getAutoFanValueLevel() {
        boolean isOk = CarSignalController.checkSelf();
        if (!isOk) {
            return 255;
        }
        CarPropertyManager carPropertyManager =
                CarSignalController.getInstance().getCarPropertyManager();
        int proValue = carPropertyManager.getIntProperty(autoFanProperty.getPropertyId(), 5);
        return autoFanProperty.getPropertyAdaptValue(proValue);
    }

    public int getHandFanValueLevel() {
        if (!isHvacFanSpeedAvailable()) {
            return 255;
        }
        CarPropertyManager carPropertyManager =
                CarSignalController.getInstance().getCarPropertyManager();
        return carPropertyManager.getIntProperty(VehiclePropertyIds.HVAC_FAN_SPEED, 5);
    }

    public boolean isSupportFanMode() {
        if (!isHvacAutoOnAvailable()) {
            return false;
        }
        CarPropertyManager carPropertyManager =
                CarSignalController.getInstance().getCarPropertyManager();
        return carPropertyManager.isPropertyAvailable(VehiclePropertyIds.HVAC_AUTO_ON, 5);
    }

    public boolean getFanModeSwitch() {
        if (!isHvacAutoOnAvailable()) {
            return false;
        }
        CarPropertyManager carPropertyManager =
                CarSignalController.getInstance().getCarPropertyManager();
        return carPropertyManager.getBooleanProperty(VehiclePropertyIds.HVAC_AUTO_ON, AREA_SEAT_ROW_1);
    }

    public boolean isSupportAutoFan() {
        boolean isOk = CarSignalController.checkSelf();
        if (!isOk) {
            return false;
        }
        CarPropertyManager carPropertyManager =
                CarSignalController.getInstance().getCarPropertyManager();
        return carPropertyManager.isPropertyAvailable(autoFanProperty.getPropertyId(), 5);
    }

    public boolean isSupportHandFan() {
        if (!isHvacFanSpeedAvailable()) {
            return false;
        }
        CarPropertyManager carPropertyManager =
                CarSignalController.getInstance().getCarPropertyManager();
        return carPropertyManager.isPropertyAvailable(VehiclePropertyIds.HVAC_FAN_SPEED, 5);
    }

    public void setAutoFanValue(int value) {
        boolean isOk = CarSignalController.checkSelf();
        if (isOk) {
            CarPropertyManager carPropertyManager =
                    CarSignalController.getInstance().getCarPropertyManager();
            carPropertyManager.setIntProperty(autoFanProperty.getPropertyId(), 5, value);
        }
    }

    public int setHandFanPreviousValue() {
        int currentValue = getHandFanValueLevel();
        LogUtils.d(TAG, "downHanFanLevel currentValue：" + currentValue);
        if (currentValue <= AppConstants.HVAC_FAN_SPEED_0) {
            return AppConstants.HVAC_FAN_SPEED_0;
        }
        currentValue--;
        LogUtils.d(TAG, "downHanFanLevel setValue：" + currentValue);
        setHandFanValue(currentValue);
        return currentValue;
    }

    public int setHandFanNextValue() {
        int currentValue = getHandFanValueLevel();
        LogUtils.d(TAG, "upHanFanLevel currentValue：" + currentValue);
        if (currentValue >= AppConstants.HVAC_HAND_FAN_SPEED_9) {
            return AppConstants.HVAC_HAND_FAN_SPEED_9;
        }
        currentValue++;
        LogUtils.d(TAG, "upHanFanLevel setValue：" + currentValue);
        setHandFanValue(currentValue);
        return currentValue;
    }

    public void setHandFanValue(int progress) {
        boolean isOk = CarSignalController.checkSelf();
        if (isOk) {
            CarPropertyManager carPropertyManager =
                    CarSignalController.getInstance().getCarPropertyManager();
            boolean propertyAvailable = isHVACPowerOnAvailable();
            LogUtils.d(TAG, "setHandFanValue HVAC_POWER_ON propertyAvailable:" + propertyAvailable);
            if (propertyAvailable) {
                boolean booleanProperty = isHVACPowerOn();
                LogUtils.d(TAG, "setHandFanValue HVAC_POWER_ON value:" + booleanProperty);
                if (booleanProperty) {
                    if (isHvacFanSpeedAvailable()) {
                        carPropertyManager.setIntProperty(
                                VehiclePropertyIds.HVAC_FAN_SPEED, 5, progress);
                    }
                } else {
                    LogUtils.d(TAG, "setHandFanValue 开启空调");
                    setHVACPowerOn(true);
                }
            }
        }
    }
}
